package io.github.l86400.component.selenium.core.support;

import io.github.l86400.util.bean.EmptyUtil;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;

/**
 * @author 86400
 * @since 2021/12/20 11:56
 */
public class ExpectedConditionUtil {
    public static ExpectedCondition<WebElement> inputSendKeys(final By location, final CharSequence keys) {
        return webDriver -> {
            WebElement el = ExpectedConditions.visibilityOfElementLocated(location).apply(webDriver);
            if (EmptyUtil.isEmpty(el)) {
                return null;
            }
            String value = el.getAttribute("value");
            if (EmptyUtil.isEmpty(value)) {
                if (EmptyUtil.isEmpty(keys)) {
                    return el;
                } else {
                    el.sendKeys(keys);
                    return inputSendKeys(location, keys).apply(webDriver);
                }
            } else {
                if (value.equals(keys)) {
                    return el;
                } else {
                    el.clear();
                    return null;
                }
            }
        };
    }

    public static ExpectedCondition<WebElement> radioChecked(final By location) {
        return radioCheck(location, true);
    }

    public static ExpectedCondition<WebElement> radioUnChecked(final By location) {
        return radioCheck(location, false);
    }

    public static ExpectedCondition<WebElement> radioCheck(final By location, final boolean check) {
        return webDriver -> {
            WebElement el = ExpectedConditions.elementToBeClickable(location).apply(webDriver);
            if (EmptyUtil.isEmpty(el)) {
                return null;
            }
            String checkedValue = el.getAttribute("checked");
            boolean elCheck = !EmptyUtil.isEmpty(checkedValue) && "true".equals(checkedValue);
            if (check && !elCheck) {
                el.click();
                return radioCheck(location, check).apply(webDriver);
            } else {
                return el;
            }
        };
    }

    public static ExpectedCondition<Boolean> urlContain(final String str, final boolean ignoreCase) {
        return webDriver -> {
            String containStr = str;
            String currentUrl = webDriver.getCurrentUrl();
            if (EmptyUtil.isEmpty(currentUrl)) {
                return EmptyUtil.isEmpty(str);
            }
            if (ignoreCase) {
                currentUrl = currentUrl.toUpperCase();
                containStr = containStr.toUpperCase();
            }
            return currentUrl.contains(containStr);
        };
    }

    public static ExpectedCondition<Boolean> titleContain(final String str, final boolean ignoreCase) {
        return webDriver -> {
            String containStr = str;
            String title = webDriver.getTitle();
            if (EmptyUtil.isEmpty(title)) {
                return EmptyUtil.isEmpty(str);
            }
            if (ignoreCase) {
                title = title.toUpperCase();
                containStr = containStr.toUpperCase();
            }
            return title.contains(containStr);
        };
    }

    public static ExpectedCondition<WebElement> textNotEmpty(final By location) {
        return webDriver -> {
            WebElement el = ExpectedConditions.visibilityOfElementLocated(location).apply(webDriver);
            if (EmptyUtil.isEmpty(el)) {
                return null;
            }
            if (!EmptyUtil.isEmpty(el.getText())) {
                return el;
            }
            return null;
        };
    }

    public static ExpectedCondition<WebElement> textNotContain(final By location, String words) {
        return webDriver -> {
            WebElement el = ExpectedConditions.visibilityOfElementLocated(location).apply(webDriver);
            if (EmptyUtil.isEmpty(el)) {
                return null;
            }
            if (EmptyUtil.isEmpty(el.getText())) {
                return null;
            }
            if (!el.getText().contains(words)) {
                return el;
            }
            return null;
        };
    }
}
